package com.lancoo.klgcourseware.ui.fragment.basicTrain;

import android.content.res.AssetFileDescriptor;
import android.graphics.Bitmap;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.media.MediaPlayer;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.ForegroundColorSpan;
import android.util.Log;
import android.view.View;
import android.view.ViewStub;
import android.view.ViewTreeObserver;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.transition.Transition;
import com.github.lzyzsd.circleprogress.DonutProgress;
import com.lancoo.klgcourseware.R;
import com.lancoo.klgcourseware.entity.WordArticulation;
import com.lancoo.klgcourseware.entity.bean.KlgCommonBean;
import com.lancoo.klgcourseware.entity.bean.KlgConstant;
import com.lancoo.klgcourseware.entity.bean.KlgDbConstant;
import com.lancoo.klgcourseware.entity.bean.SpellCharacterBean;
import com.lancoo.klgcourseware.manager.KlgLocalMediaManager;
import com.lancoo.klgcourseware.manager.KlgMediaManager;
import com.lancoo.klgcourseware.ui.activity.KlgBasicTrainActivity;
import com.lancoo.klgcourseware.ui.adapter.PronunciatioPhraseAdapter;
import com.lancoo.klgcourseware.ui.widget.CountTimeView;
import com.lancoo.klgcourseware.utils.KlgBitmapUtils;
import com.lancoo.klgcourseware.utils.KlgToolUtils;
import com.lancoo.klgcourseware.utils.KlgTrainUtils;
import com.stkouyu.LancooSkEgnManager;
import com.stkouyu.entity.LgEvaluateObj;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


/**
 * Created by pengmi on 2019/8/15 18:34
 * Description:词组发音训练
 */
public class PronunciatioPhraseTrainFragment extends BasicTrainBaseFragment implements KlgMediaManager.OnPlayListener{

    private static final String TAG = "PronunciatioPhrase";

    private final int splitTime=2000;
    private KlgMediaManager repeatMediaManager;
    private RelativeLayout rl_countTime,rl_recorder,rl_spell,rl_soundWare;
    private CountTimeView countTimeView;
    private ImageView img_completeLogo,img_pause;
    private TextView tv_alert,tv_readTime,tv_giveUp;
    private RecyclerView recyclerView;
    private DonutProgress donutProgress;
    private int totalTime;
    private PronunciatioPhraseAdapter mAdapter;
    private List<SpellCharacterBean> spellCharacterBeanList;
    PronunciatioPhraseTrainState trainState=PronunciatioPhraseTrainState.THREESECOND;
    private boolean isQuality;
    private KlgCommonBean commonBean;
    private KlgLocalMediaManager resultMediaManager;
    private WordArticulation wordArticulation;

    enum PronunciatioPhraseTrainState{//三秒倒计时，朗读作答，朗读不合格结果，音频播放，跟读作答，跟读（朗读合格）结果
        THREESECOND,READINGRECORDING,READINGRESULT,MUSICPLAYING,REPEATRECORDING,REPEATRESULT
    }


    @Override
    protected int getContentViewId() {
        return R.layout.klg_fragment_pronunciatio_phrase_train;
    }

    @Override
    protected void initView(View view) {
        commonBean = (KlgCommonBean) getArguments().getSerializable(KlgBasicTrainActivity.KEY_KLGCOMMONBEN);
        wordArticulation = (WordArticulation) getArguments().getSerializable(KEY_SPELL_ARTICULATION);
        currentTrainTag=TRAINTAG_PHONETIC_PHRASE;
        if(commonBean==null){
            showEmptyLayout();
        }else{
            initData(view);
            spliteData();
            resetTrainStyle();
            recyclerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    if(recyclerView!=null){
                        recyclerView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                        enableStartTrain(0);
                    }
                }
            });
        }
    }

    private void initData(View view){
        ViewStub viewStub = view.findViewById(R.id.viewstub_main_data);
        if(viewStub!=null){
            viewStub.inflate();
            resultMediaManager=new KlgLocalMediaManager();
            repeatMediaManager = new KlgMediaManager(getContext());
            repeatMediaManager.setUpMedia( commonBean.getUs_voice(),this);
            rl_countTime = view.findViewById(R.id.rl_count_time);
            countTimeView = view.findViewById(R.id.counttime_view);
            img_completeLogo = view.findViewById(R.id.img_complete_logo);
            tv_alert = view.findViewById(R.id.tv_spell_memory_write_alert);
            tv_readTime = view.findViewById(R.id.tv_read_player_time);
            tv_giveUp = view.findViewById(R.id.tv_pass_train);
            view.findViewById(R.id.tv_pass_train).setOnClickListener(this);
            rl_recorder=view.findViewById(R.id.rl_recorder);
            rl_spell=view.findViewById(R.id.rl_spell);
            rl_soundWare=view.findViewById(R.id.rl_sound_wave);
            recyclerView = view.findViewById(R.id.recycler_view_spell);
            img_pause = view.findViewById(R.id.img_pause);
            donutProgress = view.findViewById(R.id.donut_progress);
//            ImageView img_recorder=view.findViewById(R.id.img_recorder);
            TextView tv_usPhonetic= view.findViewById(R.id.tv_us_phonetic);
            TextView tv_meaning= view.findViewById(R.id.tv_meaning);
            tv_usPhonetic.setText(commonBean.getUs_phonetic());
            tv_meaning.setText(commonBean.getExplain());
            tv_usPhonetic.setVisibility(TextUtils.isEmpty(commonBean.getUs_phonetic())?View.GONE:View.VISIBLE);
//            AnimationDrawable animation = (AnimationDrawable)img_recorder.getDrawable();
//            animation.start();
            final ImageView img_picture=view.findViewById(R.id.img_picture);
            if(TextUtils.equals("ESP",commonBean.getKlgType())&&!TextUtils.isEmpty(commonBean.getClassicSen())){
                Glide.with(getContext()).asBitmap().load(KlgDbConstant.mediaUrl+commonBean.getClassicSen())
                        .into(new SimpleTarget<Bitmap>() {
                            @Override
                            public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
                                int width = resource.getWidth();//图片原始宽度
                                int height = resource.getHeight();//图片原始高度
//                                int scaledW = KlgToolUtils.getWidthInPx(getContext())-KlgToolUtils.dip2px(getContext(),KlgToolUtils.isPad(getContext())?120f:70f);//固定图片展示高度为180dp
                                int scaledW = KlgToolUtils.dip2px(getContext(),KlgToolUtils.isPad(getContext())?360f:240f);//固定图片展示高度为180dp
                                int scaledH = (height * scaledW) /width ;//计算出按比缩放后的宽度
//                                RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(scaledW, scaledH);
//                                RelativeLayout.LayoutParams lp= (RelativeLayout.LayoutParams) img_picture.getLayoutParams();
//                                lp.width=scaledW;
//                                lp.height=scaledH;
//                                img_picture.setLayoutParams(lp);
//                                img_picture.setImageBitmap(resource);
                                String format =commonBean.getClassicSen().substring(commonBean.getClassicSen().lastIndexOf(".")+1);
                                if(TextUtils.equals(format.toLowerCase(),"png")){
                                    img_picture.setImageBitmap(Bitmap.createScaledBitmap(resource, scaledW, scaledH, true));
                                }else{
                                    img_picture.setImageBitmap(KlgBitmapUtils.zoomImage(resource,scaledW,scaledH));
                                }

                            }
                        });
            }else{
                img_picture.setVisibility(View.GONE);
            }

            ImageView img_track01 = view.findViewById(R.id.img_track01);
            ImageView img_track02 = view.findViewById(R.id.img_track02);
            ImageView img_track03 = view.findViewById(R.id.img_track03);
            ImageView img_track04 = view.findViewById(R.id.img_track04);
            volumeAnimationControl(img_track01,true);
            volumeAnimationControl(img_track02,true);
            volumeAnimationControl(img_track03,true);
            volumeAnimationControl(img_track04,true);
            view.findViewById(R.id.img_alert).setVisibility(getArguments().getBoolean(KEY_IS_ALERT)?View.VISIBLE:View.GONE);
        }
    }

    /**
     * 分割数据
     */
    private void spliteData(){
        String klgName="";
        if(wordArticulation==null){
            klgName= commonBean.getKlgName();
        }else{
            if(TextUtils.isEmpty(wordArticulation.getSyllable())){
                klgName= wordArticulation.getKlgName();
            }else{
                klgName= wordArticulation.getSyllable();
            }
        }

        spellCharacterBeanList=new ArrayList<>();
        if(TextUtils.isEmpty(klgName)){
            return;
        }
        String[] split = klgName.split("[ ,/]");
        String lastStr="";
        SpellCharacterBean lastSpellCharacterBean=null;
        for (int i = 0; i < split.length; i++) {

            if(TextUtils.equals("(...)",split[i])||
                    TextUtils.equals("...",split[i])){
                if(lastSpellCharacterBean!=null){
                    lastSpellCharacterBean.setSpecialChar(split[i]);
                    lastSpellCharacterBean.setHasSpecialChar(true);
                }
                continue;
            }

            SpellCharacterBean spellCharacterBean=new SpellCharacterBean();
            spellCharacterBean.setCharacter(split[i]);
            if(!TextUtils.isEmpty(lastStr)&&klgName.indexOf(lastStr+"/"+split[i])!=-1){
                spellCharacterBean.setHasPoint(true);
            }
            lastSpellCharacterBean=spellCharacterBean;
            spellCharacterBeanList.add(spellCharacterBean);
            totalTime+=splitTime;
            lastStr=split[i];
        }
        if(totalTime==splitTime){
            totalTime+=1000;
        }
        mAdapter=new PronunciatioPhraseAdapter(getContext(),spellCharacterBeanList,klgName);
        recyclerView.setLayoutManager(new LinearLayoutManager(getContext(),LinearLayoutManager.HORIZONTAL,false));
        recyclerView.setAdapter(mAdapter);

    }

    /**
     * 重置拼写训练样式
     */
    private void resetTrainStyle(){
        if(rl_recorder==null){
            return;
        }
        trainState=PronunciatioPhraseTrainState.THREESECOND;
        rl_recorder.setVisibility(View.GONE);
        img_pause.setVisibility(View.GONE);
        rl_spell.setBackgroundResource(R.mipmap.klg_icon_articulate_bg);
        rl_soundWare.setVisibility(View.GONE);
        donutProgress.setVisibility(View.VISIBLE);
        donutProgress.setProgress(0);
        donutProgress.setMax(totalTime);
        recorderProgress=0;
        tv_alert.setText(R.string.klg_start_phonetic_train_alert);
        showReadTimeStyle(REPEAT_TIME);
        countTimeView.setVisibility(View.VISIBLE);
        img_completeLogo.setVisibility(View.GONE);
        countTimeView.setVisibility(View.VISIBLE);
        mAdapter.setTrainModel(true,false);
        convertView.findViewById(R.id.tv_pass_train).setVisibility(View.INVISIBLE);
        scrollIndex(recyclerView,0,spellCharacterBeanList.size(),false);
    }


    /**
     *开始训练 从滴水声音后开始
     */
    protected void startTrain(){
        Log.e(TAG,"onTrainStart");
        if(rl_recorder==null){
            return;
        }
        trainState=PronunciatioPhraseTrainState.READINGRECORDING;
        recorderProgress=0;
        rl_recorder.setVisibility(View.VISIBLE);
        donutProgress.setVisibility(View.VISIBLE);
        upDateRecordProgress();
        startCountTimeTimer();
        if(wordArticulation==null){
            startSpeechEvaluation(commonBean.getKlgName(),"");
        }else{
            startSpeechEvaluation(wordArticulation.getSyllable(),"");
        }

    }



    protected void onSuccessSpeechEvaluation(int grade, String url, LgEvaluateObj skegnResult){
        isQuality = true;
        for (int i = 0; i < skegnResult.getResult().getWords().size(); i++) {
            if(i<spellCharacterBeanList.size()){
                spellCharacterBeanList.get(i).setScores(skegnResult.getResult().getWords().get(i).getScores().getOverall());
                if( spellCharacterBeanList.get(i).getScores()< KlgConstant.SCORE_QUALITY){
                    isQuality =false;
                }
            }
        }
        if(isQuality){
            for (SpellCharacterBean spellCharacterBean:spellCharacterBeanList){
                if(spellCharacterBean.getScores()<KlgConstant.SCORE_QUALITY){
                    spellCharacterBean.setScores(KlgConstant.SCORE_QUALITY);
                }
            }
        }
//        isQuality=true;
        showPronuncePhraseTrainResult(isQuality,grade);
    }

    /**
     * 中止当前的训练
     */
    protected void pauseCurrentSubTrain(boolean isReset){
        Log.e("aaaa","中止当前的训练:"+isReset);
        if(repeatMediaManager!=null){
            repeatMediaManager.pause();
        }
        pauseMeidaPlayer();
//        resetTrainStyle();
        if(isReset){
            resetTrainStyle();
        }else {
            if(rl_recorder!=null){
                rl_recorder.setVisibility(View.GONE);
                img_pause.setVisibility(View.GONE);
//            rl_recorder.setVisibility(View.VISIBLE);
//            img_pause.setVisibility(View.VISIBLE);
                donutProgress.setVisibility(View.INVISIBLE);
                rl_soundWare.setVisibility(View.GONE);
                rl_countTime.setVisibility(View.GONE);
            }
        }


    }




    /**
     * 跟读训练跟读阶段3，2，1倒计时
     */
    protected void upDateSecondCountTime(){

        if(secondCountTime==0){//进入跟读录音作答阶段
            pauseSecondTimer();
            if(rl_soundWare!=null){
                rl_soundWare.setVisibility(View.GONE);
                trainState=PronunciatioPhraseTrainState.REPEATRECORDING;
                startDripMusic();
            }
        }else{
            showReadTimeStyle(secondCountTime);
        }

    }

    /**
     * 作答评阅结束2s倒计时
     * @param progress
     * @param totalProgress
     */
    protected void upDateResultCountTime(int progress,int totalProgress){
        Log.e("aaaaa",TAG+"作答评阅结束2s倒计时");
        if(countTimeView==null){
            return;
        }
        if( trainState==PronunciatioPhraseTrainState.MUSICPLAYING){
            return;
        }
        countTimeView.setAngle(progress,totalProgress);
        rl_countTime.setVisibility(progress>=totalProgress?View.GONE:View.VISIBLE);
        if(progress==totalProgress) {
            pauseSecondTimer();
            Log.e("aaaaaa","trainState:"+trainState);
            if(trainState==PronunciatioPhraseTrainState.READINGRESULT){//作答不合格，即将进入系统带读阶段
                showMediaPlayStyle();
            }else if(trainState==PronunciatioPhraseTrainState.REPEATRESULT){
                if(isQuality){
                    enterNextTrainModel();
                }else{
                    resetTrainStyle();
                    enableStartTrain(0);
                }
            }
        }
    }

    /**
     *  展示评阅结果样式
     * @param isQuality
     */
    private void showPronuncePhraseTrainResult(boolean isQuality,int score){
        if(rl_recorder==null){
            return;
        }
        rl_recorder.setVisibility(View.GONE);
        rl_countTime.setVisibility(View.VISIBLE);
        countTimeView.setAngle(0,TRAINRESULT_TIME);
        mAdapter.setTrainModel(false,true);
        tv_alert.setVisibility(View.VISIBLE);
        convertView.findViewById(R.id.tv_pass_train).setVisibility(View.VISIBLE);
        quesResultMuiscPlayer(isQuality);
        if(trainState==PronunciatioPhraseTrainState.READINGRECORDING){
            Log.e("aaaa","朗读结束");
            if(isQuality){//合格直接去最后一个流程
                trainState=PronunciatioPhraseTrainState.REPEATRESULT;
                if(getArguments().getBoolean(KEY_ISMORE_ENTER)){
                    tv_alert.setText(R.string.klg_result_exit_train_for_pronounce);
                    tv_giveUp.setVisibility(View.GONE);
                }else{
                    tv_alert.setText(R.string.klg_result_pronounce_phrase_reading_correct);
                }
                countTimeView.setVisibility(View.GONE);
                img_completeLogo.setVisibility(View.VISIBLE);
                tv_giveUp.setText(R.string.klg_train_again);
            }else{//不合格走朗读结束流程
                trainState=PronunciatioPhraseTrainState.READINGRESULT;
                tv_alert.setText(R.string.klg_result_pronounce_reading_error);
                tv_giveUp.setText(R.string.klg_pass_train);
                rl_spell.setBackgroundResource(R.mipmap.klg_icon_articulate_yellow_bg);
            }
        }else{
            trainState=PronunciatioPhraseTrainState.REPEATRESULT;
            if(isQuality){
                convertView.setVisibility(View.GONE);
                img_completeLogo.setVisibility(View.VISIBLE);
                if(getArguments().getBoolean(KEY_ISMORE_ENTER)){
                    tv_alert.setText(R.string.klg_result_exit_train_for_pronounce);
                }else{
                    tv_alert.setText(R.string.klg_result_pronounce_phrase_reading_correct);
                }
                tv_giveUp.setText(R.string.klg_train_again);
            }else {
                tv_alert.setText(R.string.klg_result_pronounce_reading_error);
                tv_giveUp.setText(R.string.klg_pass_train);
                rl_spell.setBackgroundResource(R.mipmap.klg_icon_articulate_yellow_bg);
            }
        }
        updateTrainResult(isQuality,score);
        startSecondTimer();
    }

    /**
     * 展示系统带读样式
     */
    private void showMediaPlayStyle(){
        resetTrainStyle();
        rl_soundWare.setVisibility(View.VISIBLE);
        trainState=PronunciatioPhraseTrainState.MUSICPLAYING;
        secondCountTime=REPEAT_TIME;
        trainCountTime=MEDIAREPEAT_TIME;
        if(repeatMediaManager!=null){
            repeatMediaManager.seekTo(0);
            repeatMediaManager.start();
        }
        startSecondTimer();
    }

    private void showReadTimeStyle(int readTime){
        if(tv_readTime!=null){
            String readTimeStr=String.format(getString(R.string.klg_repeat_time_count),readTime);
            SpannableString spannableString=new SpannableString(readTimeStr);
            spannableString.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.klg_high_list_color)),2,3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            tv_readTime.setText(spannableString);
        }
    }

    /**
     * 恢复，继续训练
     */
    protected void continueTrain(){
        if(rl_recorder==null){
            return;
        }
        rl_recorder.setVisibility(View.GONE);
        img_pause.setVisibility(View.GONE);
        switch (trainState){
            case THREESECOND:
                resetTrainStyle();
                enableStartTrain(0);
                break;
            case READINGRECORDING:
                donutProgress.setVisibility(View.VISIBLE);
                mAdapter.setTrainModel(true,false);
                startDripMusic();
                break;
            case READINGRESULT:
                startSecondTimer();
                break;
            case MUSICPLAYING:
                showMediaPlayStyle();
                break;
            case REPEATRECORDING:
                donutProgress.setVisibility(View.VISIBLE);
                mAdapter.setTrainModel(true,false);
                startDripMusic();
                break;
            case REPEATRESULT:
                startSecondTimer();
                break;
        }

    }

    protected void resetPronounceTrain(){
        Log.e("aaaa","进到词组的重新训练了。。。。");
        resetTrainStyle();
    }


    @Override
    public void onComplete() {

    }

    @Override
    public void onStartError() {

    }

    @Override
    public void onPausePlay() {

    }

    @Override
    public void onSourceError() {

    }


    @Override
    public void onResumePlay() {

    }

    @Override
    public void onStopPlay() {

    }

    @Override
    public void onPrepare() {

    }

    @Override
    public void onBufferingUpdate(MediaPlayer mp, int percent) {

    }

    @Override
    public void onPause() {
        super.onPause();
        if(repeatMediaManager!=null){
            repeatMediaManager.pause();
        }
        pauseMeidaPlayer();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if(repeatMediaManager!=null){
            repeatMediaManager.release();
        }
        if(resultMediaManager!=null){
            resultMediaManager.release();
        }
    }

    /**
     * 3,2,1s倒计时
     * @param progress
     * @param totalProgress
     */
    protected void updateCountTime(int progress,int totalProgress){
        Log.e("aaaa","发音训练321:"+progress+"...."+totalProgress);
        if(convertView==null){
            return;
        }
        rl_countTime.setVisibility(progress==totalProgress?View.GONE:View.VISIBLE);
        countTimeView.setAngle(progress,totalProgress);
    }


    /**
     * 更新录音作答时长进度
     */
    protected void upDateRecordProgress(){
        if(donutProgress!=null){
            donutProgress.setProgress(recorderProgress);
            if(recorderProgress>(mAdapter.getShowIndex()+1)*splitTime){
                mAdapter.changeRepeat(recorderProgress/splitTime);
                scrollIndex(recyclerView,recorderProgress/splitTime,spellCharacterBeanList.size(),true);
            }
        }
        if(recorderProgress>=totalTime){
            Log.e("aaaa","作答结束");
            destroyCountTimeTimer();
            stopSpeechEvaluation(true);
        }
        audioAnimation();
    }


    protected void scrollIndex(RecyclerView recyclerView, int position, int totalSize, boolean forward){
        if(forward){
            recyclerView.smoothScrollToPosition(totalSize-position>2?position:position+2);
        }else{
//            recyclerView.smoothScrollToPosition(0);
            recyclerView.scrollToPosition(0);
        }
    }

    protected void volumeAnimationControl(ImageView img, boolean isAnimation){
        if(img!=null&&img.getVisibility()==View.VISIBLE){
            if(isAnimation){
//                img.setImageResource(R.drawable.lgklg_animation_list_volume_cyan);
                img.setBackground(null);
                ((AnimationDrawable)img.getDrawable()).start();
            }else{
//                img.setImageResource(R.drawable.lgklg_volume_cyan_3);
                img.setBackgroundResource(R.drawable.klg_volume_cyan_3);
                ((AnimationDrawable)img.getDrawable()).stop();
                ((AnimationDrawable)img.getDrawable()).selectDrawable(0);
            }
        }
    }

    private void audioAnimation(){
        float volume = LancooSkEgnManager.getInstance(getContext()).getVolume();
        try {
            ImageView imgRecorder = convertView.findViewById(R.id.img_recorder);
            if(imgRecorder==null){
                return;
            }
            LayerDrawable drawable =(LayerDrawable) imgRecorder.getDrawable();
            Drawable clipDrawable = drawable.getDrawable(1);

            clipDrawable.setLevel(KlgTrainUtils.getAudioDBLevel((int)volume));
        }catch (Exception e){
            e.printStackTrace();
        }

    }

    private void pauseMeidaPlayer(){
        if(resultMediaManager!=null){
            resultMediaManager.pause();
        }
    }

    protected void quesResultMuiscPlayer(boolean isCorrect){
        if(resultMediaManager==null){
            return;
        }
        try {
            AssetFileDescriptor assetFileDescriptor = getContext().getAssets().openFd(isCorrect?"klg_record_correct.mp3":"klg_record_error.mp3");
            resultMediaManager.setUpMedia(assetFileDescriptor, new KlgLocalMediaManager.OnPlayListener() {
                @Override
                public void onComplete() {

                }

                @Override
                public void onStartError() {

                }

                @Override
                public void onPausePlay() {

                }

                @Override
                public void onSourceError() {

                }

                @Override
                public void onResumePlay() {

                }

                @Override
                public void onStopPlay() {

                }

                @Override
                public void onPrepare() {
                    if(resultMediaManager!=null){
                        resultMediaManager.start();
                    }
                }

                @Override
                public void onBufferingUpdate(MediaPlayer mp, int percent) {

                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}
